package com.digital.smartgrow.common.config.mysql;


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;


/**
 * mybatis 管理第一个数据源(常用的数据源)
 */
@Configuration
@MapperScan(basePackages = "com.digital.smartgrow.dao", sqlSessionTemplateRef = "genericSqlSessionTemplate")
public class DataSourceConfig {

    @Value("${spring.datasource.filters}")
    private String filters;
    @Value("${spring.datasource.driver-class-name}")
    private String driverClass;
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String user;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.initial-size}")
    private int initial_size;
    @Value("${spring.datasource.min-idle}")
    private int min_idle;
    @Value("${spring.datasource.max-active}")
    private int max_active;
    @Value("${spring.datasource.max-wait}")
    private long max_wait;
    @Value("${spring.datasource.time-between-eviction-runs-millis}")
    private long time_between_eviction_runs_millis;
    @Value("${spring.datasource.min-evictable-idle-time-millis}")
    private long min_evictable_idle_time_millis;
    @Value("${spring.datasource.validation-query}")
    private String validation_query;
    @Value("${spring.datasource.test-while-idle}")
    private boolean test_while_idle;
    @Value("${spring.datasource.test-on-borrow}")
    private boolean test_on_borrow;
    @Value("${spring.datasource.test-on-return}")
    private boolean test_on_return;
    @Value("${spring.datasource.pool-prepared-statements}")
    private boolean pool_prepared_statements;
    @Value("${spring.datasource.max-pool-prepared-statement-per-connection-size}")
    private int max_pool_prepared_statement_per_connection_size;

    @Autowired
    private PaginationInterceptor paginationInterceptor;

    /**
     * 设置数据源
     *
     * @return
     * @throws SQLException
     */
    @Bean(name = "genericDataSource")
    @Primary //必须加注解，不然会报错，下一个类不需要添加
    public DataSource genericDataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setFilters(filters);
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        dataSource.setInitialSize(initial_size);
        dataSource.setMinIdle(min_idle);
        dataSource.setMaxActive(max_active);
        dataSource.setMaxWait(max_wait);
        dataSource.setTimeBetweenConnectErrorMillis(time_between_eviction_runs_millis);
        dataSource.setMinEvictableIdleTimeMillis(min_evictable_idle_time_millis);
        dataSource.setValidationQuery(validation_query);
        dataSource.setTestWhileIdle(test_while_idle);
        dataSource.setTestOnBorrow(test_on_borrow);
        dataSource.setTestOnReturn(test_on_return);
        dataSource.setPoolPreparedStatements(pool_prepared_statements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(max_pool_prepared_statement_per_connection_size);
        return dataSource;
    }


    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("genericDataSource") DataSource dataSource) {
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);
        return manager;
    }


    /**
     * SqlSessionFactory
     *
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "genericSqlSessionFactory")
    public SqlSessionFactory genericSqlSessionFactory(@Qualifier("genericDataSource") DataSource dataSource) throws Exception {
//        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //添加XML目录
        try {
            //添加mybatis-plus分页插件
            Interceptor[] interceptors = {paginationInterceptor};
            bean.setPlugins(interceptors);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));
            return bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }


    /**
     * SqlSessionTemplate
     *
     * @param sqlSessionFactory
     * @return
     */
    @Bean(name = "genericSqlSessionTemplate")
    public SqlSessionTemplate genericSqlSessionTemplate(@Qualifier("genericSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }


}
